﻿using System;
using System.Collections.Generic;



namespace Bibylon.BehafX.StateMachine.concept
{
    internal enum Status
    {
        Openned,  // not yet initialised...

        Successful,
        Failed,
        Running,

        Undefined // Exception occured...
    }


    /// <summary>
    /// 'Node-' item in the Behavior Tree.
    /// </summary>
    internal abstract class node
    {
        /// <summary>
        /// C'tor ...
        /// </summary>
        public node(string name, int nid, node parent)
        {
            Symbol = name;           
            handle = nid;

            Parent = parent;

            QueryStatus = Status.Openned;
            
            Children = null;
        }

        /// <summary>
        /// Category of this: 
        /// composite, condition, decorator or action; etc.
        /// </summary>
        public abstract  string Category { get; }

        /// <summary>
        /// Unique type id, used to identify this in stream loading
        /// </summary>
        public abstract /**System.Guid*/ int Typeid { get; }

        /// <summary>
        /// Human-readable [Displaying] name string.
        /// </summary>
        public string Symbol { get; set; }

        /// <summary>
        /// Numeric handle id to the this,
        /// </summary>
        public int handle { get; protected set; }

        /// <summary>
        /// Execution returned value of .
        /// </summary>
        public Status QueryStatus { get; protected set; }

        /// <summary>
        /// parent node to this
        /// </summary>
        public node Parent { get; set; } 

        /// <summary>
        /// Child-nodes housed by this, 
        /// @Remark: this maybe null list instead of an empty one,
        /// indicate who CANNOT have any children.
        /// </summary>
        public virtual List<node> Children { get; protected set; }

        /// <summary>
        /// trace down the execution of this block, get everything properly
        /// </summary>
        internal virtual void evaluate(object agent, object any)
        {
            // TODO: register this execution.
            int result = (int)Status.Running;
            try
            {
                result = execute(agent, any);
            }
            catch (System.Exception except)
            {
                // TODO: save this exception.
                QueryStatus = Status.Undefined;
            }

            // messaging a feedback to parent.
            feedback( agent, result );
        }

        /// <summary>
        /// try to get the job done the node designed to get along with.
        /// </summary>
        internal abstract int execute(object agent, object any);

        ///
        /// post-exe phase, to report the execution and trigger appropriate events
        internal virtual void feedback(object agent, int state)
        {
            switch (this.QueryStatus)
            {
                default: /* Unhandled cases,. */
                    /** no-op */ break;
            }
        }


        /// <summary>
        /// force to shutdown exection of this behavior node .. 
        /// when a branch with higher priority executed, teardown nodes in previous branch
        /// </summary>
        internal virtual void shutdown(object agent, bool applyToChildren = true)
        {
            // Not yet implemented!!
        }

    }
}
